from typing import Union, List

import httpx


class AzsHttpClient:
    DEFAULT_TIMEOUT = httpx.Timeout(timeout=600.0, connect=5.0)
    DEFAULT_MAX_RETRIES = 2

    @staticmethod
    def process_resp(response, response_type) -> Union[dict, List]:
        if response_type == "json":
            resp_json = response.json()
            if response.status_code != 200 and resp_json.get("code") != 200:
                raise Exception(f"login failed: {resp_json}")
            return resp_json['data']
        elif response_type == "text":
            return response.text.split("\n")
        else:
            raise Exception(f"unsupported response type: {response_type}")

    @classmethod
    def post(cls, url: str, params: dict = {}, headers: dict = {}, response_type: str = "json") -> Union[dict, List]:
        with httpx.Client(timeout=cls.DEFAULT_TIMEOUT) as client:
            response = client.post(url, json=params, headers=headers)
            return cls.process_resp(response, response_type)

    @classmethod
    def get(cls, url: str, params: dict = {}, headers: dict = {}, response_type: str = "json") -> Union[dict, List]:
        with httpx.Client(timeout=cls.DEFAULT_TIMEOUT) as client:
            response = client.get(url, params=params, headers=headers)
            return cls.process_resp(response, response_type)

    @classmethod
    def stream_post(cls, url: str, params: dict = {}, headers: dict = {}):
        with httpx.Client(timeout=cls.DEFAULT_TIMEOUT) as client:
            with client.stream("post", url=url, json=params, headers=headers) as response:
                if response.status_code == 200:
                    for line in response.iter_lines():
                        if line:
                            yield line
                else:
                    raise Exception(f"Request failed with status code {response.status_code}")
